using System;
using Sce.Pss.Core;
using Sce.Pss.Core.Environment;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Imaging;
using Sce.Pss.Core.Input;
using Sce.Pss.HighLevel.GameEngine2D;
using Sce.Pss.HighLevel.GameEngine2D.Base;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;
using System.Web;
using System.Net;

namespace KryschenApp
{
	public class MeineApp
	{
		private Scene meineScene;
		private List<KryschenSprite> bilder=new List<KryschenSprite>();
		private int currentSprite=0;
		
		private Vector2 outOfScope = new Vector2(-10000,-10000);
		
		public AppZustand ZustandDerApp {get;set;}
		
		protected FpsUeberwacher FpsUeberwacherInstanz{get;set;} 		
		
		public MeineApp ()
		{
			ZustandDerApp = AppZustand.Init;			
		}

		void SceneErzeugen ()
		{
			meineScene = new Scene();
			meineScene.Camera.SetViewFromViewport();
			
			MagazinUebersicht m;
			XmlSerializer ser = new XmlSerializer(typeof(MagazinUebersicht));
			
			using(FileStream fs = new FileStream(@"/Application/MagazinUebersicht.xml", FileMode.Open))
			{
				m = (MagazinUebersicht)ser.Deserialize(fs);
			}
			
			Magazin m1 = m.AlleMagazine[0];	
			int i=0;
			foreach (Element e in m1.Elemente)
			{				
				bilder.Add(CreateBild(e, ""+i++, m1));
			}
			
			KryschenSprite spriteBlau = bilder[currentSprite];
			SpriteZentrieren( spriteBlau);
			
//			meineScene.AddChild(spriteBlau);
		}

		Vector2 GroesseErmitteln (Element e, TextureInfo ti)
		{
			return new Vector2(ti.TextureSizef.X, ti.TextureSizef.Y); //new Vector2(e.Breite==-1 || e.Breite==0? ti.TextureSizef.X: e.Breite,e.Hoehe==-1||e.Hoehe==0? ti.TextureSizef.Y: e.Hoehe);
		}
		
		public KryschenSprite CreateBild(Element e, string fileEnd, Magazin m)
		{
			TextureInfo textureInfo = LoadTexture(e, e.Dateiname, fileEnd, m);
			
			KryschenSprite sprite = new KryschenSprite(textureInfo);
			sprite.Quad.S = GroesseErmitteln (e,textureInfo);
			sprite.Position = outOfScope;
			
			meineScene.AddChild(sprite);
			
			return sprite;
		}		
		
		public void Initialize ()
		{
			// Set up the graphics system
			//graphics = new GraphicsContext ();			
			
			FpsUeberwacherInstanz = new FpsUeberwacher(FpsMoeglichkeiten.Fps60);
			
			Director.Initialize();			
			//Director.Instance.GL.Context.SetClearColor(Colors.Red);

			SceneErzeugen ();
			
			Director.Instance.RunWithScene(meineScene, true);
		}

		public void StartRunning()
		{
			// Set up the graphics system
			if (ZustandDerApp!=AppZustand.Init)
			{
				throw new ArgumentException("App im falschen Zustand!");	
			}
			ZustandDerApp = AppZustand.AppRunning;
		}
		
		public void Wait()
		{
			FpsUeberwacherInstanz.WarteFuerSync();	
		}

		void SpriteZentrieren (KryschenSprite spriteBlau)
		{
			if (spriteBlau.AktuelleDrehungPos == DrehungEnum.Null) {
			
				if (spriteBlau.Quad.S.X>spriteBlau.Quad.S.Y) {
					spriteBlau.Position = new Vector2(
						0//spriteBlau.Quad.S.X,
						,0);//spriteBlau.Quad.S.Y);
				}
				if (spriteBlau.Quad.S.Y>spriteBlau.Quad.S.X) {
					spriteBlau.Position = new Vector2(
						meineScene.Camera2D.Center.X/2//spriteBlau.Quad.S.X,
						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Quad.S.Y);
				}
			}

			if (spriteBlau.AktuelleDrehungPos == DrehungEnum.Neunzig) {
			
				if (spriteBlau.Quad.S.X>spriteBlau.Quad.S.Y) {
					spriteBlau.Position = new Vector2(
						meineScene.Camera2D.Center.X+200//spriteBlau.Quad.S.X,
						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Quad.S.Y);
				}
				if (spriteBlau.Quad.S.Y>spriteBlau.Quad.S.X) {
					spriteBlau.Position = new Vector2(
						spriteBlau.Quad.S.X+400, 0);
						//meineScene.Camera2D.Center.X/2//spriteBlau.Quad.S.X,
//						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Qu//ad.S.Y);
				}
			}
			if (spriteBlau.AktuelleDrehungPos == DrehungEnum.HundertAchtzig) {
			
				if (spriteBlau.Quad.S.X>spriteBlau.Quad.S.Y) {
					spriteBlau.Position = new Vector2(
						0, spriteBlau.Quad.S.X*2);//spriteBlau.Quad.S.Y);
				}
				if (spriteBlau.Quad.S.Y>spriteBlau.Quad.S.X) {
					spriteBlau.Position = new Vector2(
						700, 950);//spriteBlau.Quad.S.Y);
						//meineScene.Camera2D.Center.X/2//spriteBlau.Quad.S.X,
//						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Qu//ad.S.Y);
				}
			}			
			if (spriteBlau.AktuelleDrehungPos == DrehungEnum.ZweiHundertSiebzig) {
			
				if (spriteBlau.Quad.S.X>spriteBlau.Quad.S.Y) {
					spriteBlau.Position = new Vector2(
						meineScene.Camera2D.Center.X/2//spriteBlau.Quad.S.X,
						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Quad.S.Y);
				}
				if (spriteBlau.Quad.S.Y>spriteBlau.Quad.S.X) {
					spriteBlau.Position = new Vector2(
						0, spriteBlau.Quad.S.Y-400);//spriteBlau.Quad.S.Y);
						//meineScene.Camera2D.Center.X/2//spriteBlau.Quad.S.X,
//						,-spriteBlau.Quad.S.Y+544);//spriteBlau.Qu//ad.S.Y);
				}
			}
			/*
			spriteBlau.Position = new Vector2(
				meineScene.Camera2D.Center.X - (spriteBlau.Quad.S.X / 2),
				meineScene.Camera2D.Center.Y - (spriteBlau.Quad.S.Y / 2))
				;*/
		}
		
		public void Update ()
		{
			// Query gamepad for current state
			var gamePadData = GamePad.GetData (0);
			
			KryschenSprite spriteBlau = bilder[currentSprite];
			
			//if (gamePadData.IstLgedrueckt())
				if (gamePadData.IstLgedrueckt())
			{
				currentSprite--;
				
				if (currentSprite==-1)
				{
					currentSprite = bilder.Count-1;
				}				
				spriteBlau.Position = outOfScope;
				
				spriteBlau = bilder[currentSprite];
				SpriteZentrieren (spriteBlau);// meineScene.Camera2D.Center;
				
			}
			if (gamePadData.IstRgedrueckt())
			{
				currentSprite++;
				
				if (currentSprite==bilder.Count)
				{
					currentSprite = 0;
				}				
				spriteBlau.Position = outOfScope;
				
				spriteBlau = bilder[currentSprite];
				//spriteBlau.Position = meineScene.Camera2D.Center;
				SpriteZentrieren (spriteBlau);// meineScene.Camera2D.Center;
			}
			if (gamePadData.IstStartgedrueckt())
			{
				this.ZustandDerApp = AppZustand.EndApp;
			}
			Vector2 position = spriteBlau.Position;
			Vector2 groesse = spriteBlau.Quad.S;
			
			if (gamePadData.IstDigitalNachObenGedrueckt())
			{
				position = new Vector2(position.X, position.Y + 10);
			}
			if (gamePadData.IstDigitalNachUntenGedrueckt())
			{
				position = new Vector2(position.X, position.Y - 10);
			}
			if (gamePadData.IstDigitalNachRechtsGedrueckt())
			{
				position = new Vector2(position.X+10, position.Y);
			}
			if (gamePadData.IstDigitalNachLinksGedrueckt())
			{
				position = new Vector2(position.X-10, position.Y);
			}
			
			spriteBlau.Position = position;			
			
			if (gamePadData.IstChrossGedrueckt())
			{
				double x = groesse.X * 1.20;
				double y = groesse.Y * 1.20;
				groesse = new Vector2((float)x,(float)y);
				spriteBlau.Quad.S = groesse;
				
				//SpriteZentrieren(spriteBlau);
			}
			if (gamePadData.IstCircleGedrueckt())
			{
				double x = groesse.X / 1.20;
				double y = groesse.Y / 1.20;
				groesse = new Vector2((float)x,(float)y);
				spriteBlau.Quad.S = groesse;
				
				//SpriteZentrieren(spriteBlau);
			}
			if (gamePadData.IstTriangleGedrueckt())
			{
				spriteBlau.Um90GradDrehen();
								
				SpriteZentrieren(spriteBlau);
			}
			
			Director.Instance.Update();			
		}

		public void Render ()
		{
			Director.Instance.Render();
			Director.Instance.GL.Context.SwapBuffers();
			Director.Instance.PostSwap();
		}
		
		internal static TextureInfo LoadTexture(Element e, string filename, string filenameEnd, Magazin m)
		{
			e.lokalDateiname = string.Format("/Application/g/{1}-{0}.jpg", filenameEnd, m.Name);
			
			FileInfo fI = new FileInfo(e.lokalDateiname);
			
			if (!fI.Exists) {
				if (filename.ToLower().StartsWith("http")) {
					byte[] b;
					using (WebClient w = new WebClient()) {
						b=w.DownloadData(filename);
					}
					
					using (FileStream fs = new FileStream(e.lokalDateiname, FileMode.Create)) 
					{
						fs.Write(b,0,b.Length);
					}
				}
			}
			
			
			return new TextureInfo(new Texture2D(e.lokalDateiname, false));
		}			
	}
}

